package com.mcp.converter.application.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mcp.converter.domain.parser.MybatisXMLParser;
import com.mcp.converter.domain.parser.IfpXMLParser;
import com.mcp.converter.domain.parser.impl.IbatisXMLParserImpl;
import com.mcp.converter.shared.response.analysis.BatchAnalysisResponse;
import com.mcp.converter.shared.response.analysis.FallbackCompatibilityResult;
import com.mcp.converter.shared.response.analysis.CompatibilityReclassificationResult;
import com.mcp.converter.shared.response.analysis.CompatibilityAnalysisResult;
import com.mcp.converter.shared.response.analysis.CompatibilityStatisticsResult;
import com.mcp.converter.shared.response.analysis.IfpAnalysisContext;
import com.mcp.converter.shared.response.sql.SqlExtractionResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * XML兼容性分析服务
 * 负责处理XML文件兼容性分析的辅助功能
 * 
 * @author zengxiong
 */
@Slf4j
@Service
public class XmlCompatibilityAnalysisService {
    private static final double PERCENTAGE_MULTIPLIER = 100.0;
    private static final double PERCENTAGE_PRECISION = 100.0;
    
    private final SqlAnalysisService sqlAnalysisService;
    private final MybatisXMLParser mybatisXMLParser;
    private final IfpXMLParser ifpXMLParser;

    private final IbatisXMLParserImpl ibatisXMLParser;

    public XmlCompatibilityAnalysisService(SqlAnalysisService sqlAnalysisService, 
                                           MybatisXMLParser mybatisXMLParser,
                                           IfpXMLParser ifpXMLParser,
                                           IbatisXMLParserImpl ibatisXMLParser) {
        this.sqlAnalysisService = sqlAnalysisService;
        this.mybatisXMLParser = mybatisXMLParser;
        this.ifpXMLParser = ifpXMLParser;
        this.ibatisXMLParser = ibatisXMLParser;
    }
    
    /**
     * 验证输入参数
     */
    public String validateInput(String xmlFilePath, long startTime) {
        if (xmlFilePath == null || xmlFilePath.trim().isEmpty()) {
            return sqlAnalysisService.buildErrorResponse("文件路径不能为空", xmlFilePath, startTime);
        }
        return null;
    }
    
    /**
     * 提取和解析SQL语句
     */
    public IfpAnalysisContext extractAndParseSqls(String xmlFilePath, ObjectMapper mapper, long startTime) 
            throws JsonProcessingException {
        // 提取ifp框架XML中的SQL语句
        String extractResult = ifpXMLParser.extractSQLsFromXML(xmlFilePath);
        JsonNode extractNode = mapper.readTree(extractResult);
        
        // 检查success字段是否存在且为false
        JsonNode successNode = extractNode.get("success");
        if (successNode == null || !successNode.asBoolean()) {
            String fileName = ifpXMLParser.extractFileNameFromPath(xmlFilePath);
            // 尝试获取 errorMessage 字段，如果不存在则尝试 error 字段
            JsonNode errorMessageNode = extractNode.get("errorMessage");
            if (errorMessageNode == null) {
                errorMessageNode = extractNode.get("error");
            }
            String errorMessage = errorMessageNode != null ? errorMessageNode.asText() : "未知解析错误";
            String errorResponse = sqlAnalysisService.buildErrorResponse(
                "ifp框架SQL提取失败: " + errorMessage, 
                fileName, startTime);
            return IfpAnalysisContext.withError(errorResponse);
        }
        
        // 智能SQL提取和校验
        SqlExtractionResult extractionResult = sqlAnalysisService.extractAndValidateSqls(extractNode, mapper);
        List<String> validSqls = extractionResult.validSqls();
        List<JsonNode> sqlDetailsList = extractionResult.sqlDetailsList();
        
        // 检查是否有有效的SQL语句（允许存在空SQL）
        int validSqlCount = extractNode.has("validSqlCount") ? extractNode.get("validSqlCount").asInt() : validSqls.size();
        int emptySqlCount = extractNode.has("emptySqlCount") ? extractNode.get("emptySqlCount").asInt() : 0;
        
        log.info("SQL提取结果 - 有效SQL: {}, 空SQL: {}, 总计: {}", validSqlCount, emptySqlCount, validSqlCount + emptySqlCount);
        
        // 只有当完全没有找到任何SQL（包括空SQL）时才认为是错误
        if (validSqls.isEmpty() && sqlDetailsList.isEmpty() && (validSqlCount + emptySqlCount) == 0) {
            String fileName = ifpXMLParser.extractFileNameFromPath(xmlFilePath);
            String errorResponse = sqlAnalysisService.buildErrorResponse("未找到任何SQL语句", fileName, startTime);
            return IfpAnalysisContext.withError(errorResponse);
        }
        
        // 如果只有空SQL，给出警告但不认为是错误
        if (validSqlCount == 0 && emptySqlCount > 0) {
            log.warn("文件 {} 中只包含 {} 个空SQL语句，没有有效的SQL内容", xmlFilePath, emptySqlCount);
        }
        
        return IfpAnalysisContext.success(extractNode, validSqls, sqlDetailsList, xmlFilePath);
    }
    
    /**
     * 执行兼容性分析
     */
    public CompatibilityAnalysisResult performCompatibilityAnalysis(List<String> validSqls) {
        // 批量兼容性分析
        BatchAnalysisResponse batchResult;
        if (!validSqls.isEmpty()) {
            batchResult = sqlAnalysisService.analyzeBatch(validSqls);
        } else {
            batchResult = createEmptyBatchResult();
        }
        
        // 增强兼容性检测
        FallbackCompatibilityResult fallbackResult = ifpXMLParser
            .performFallbackCompatibilityCheck(validSqls, batchResult);
        if (fallbackResult == null) {
            fallbackResult = new FallbackCompatibilityResult();
        }
        
        // 智能错误重分类
        CompatibilityReclassificationResult reclassificationResult = ifpXMLParser.performIntelligentReclassification(
            batchResult, validSqls);
        
        return new CompatibilityAnalysisResult(batchResult, fallbackResult, reclassificationResult);
    }
    
    /**
     * 构建ifp兼容性分析响应
     */
    public String buildIfpCompatibilityResponse(IfpAnalysisContext context, 
                                                CompatibilityAnalysisResult analysisResult,
                                                ObjectMapper mapper) throws JsonProcessingException {
        String fileName = ifpXMLParser.extractFileNameFromPath(context.getXmlFilePath());
        JsonNode sqlStatements = context.getExtractNode().get("sqlStatements");
        int totalSqlCount = sqlStatements.size();
        int validSqlCount = context.getValidSqls().size();
        
        // 计算兼容性统计
        CompatibilityStatisticsResult stats = calculateCompatibilityStatistics(analysisResult, validSqlCount);
        
        // 构建响应对象
        ObjectNode response = mapper.createObjectNode();
        response.put("success", true);
        response.put("fileName", fileName);
        response.put("frameworkType", "ifp");
        response.put("businessLogicId", context.getExtractNode().get("businessLogicId").asText());
        response.put("totalSqlCount", totalSqlCount);
        response.put("validSqlCount", validSqlCount);
        response.put("compatibilityPercentage", stats.getCompatibilityPercentage());
        response.put("hasCompatibilityAnalysis", validSqlCount > 0);
        
        // 添加修正后的统计信息
        response.put("correctedIncompatibleCount", stats.getIncompatibleCount());
        response.put("correctedCompatibleCount", analysisResult.batchResult().getCompatibleCount());
        response.put("correctedErrorCount", analysisResult.reclassificationResult().correctedErrorCount());
        
        // 添加批量分析结果
        ObjectNode batchAnalysisNode = buildBatchAnalysisNode(
            analysisResult, context.getValidSqls(), mapper);
        response.set("batchAnalysis", batchAnalysisNode);
        
        // 添加SQL详情
        ArrayNode sqlDetailsArray = mapper.createArrayNode();
        context.getSqlDetailsList().forEach(sqlDetailsArray::add);
        response.set("sqlDetails", sqlDetailsArray);
        
        // 添加摘要信息
        String summary = buildSummary(fileName, totalSqlCount, validSqlCount, 
            analysisResult.batchResult().getCompatibleCount(),
            stats.getIncompatibleCount(),
            analysisResult.reclassificationResult().correctedErrorCount());
        response.put("summary", summary);
        response.put("timestamp", LocalDateTime.now().toString());
        
        String result = mapper.writeValueAsString(response);
        log.info("ifp框架XML兼容性分析完成: {}", fileName);
        return result;
    }
    
    /**
     * 计算兼容性统计信息
     */
    public CompatibilityStatisticsResult calculateCompatibilityStatistics(
            CompatibilityAnalysisResult analysisResult, int validSqlCount) {
        // 获取批量分析结果
        int actualCompatibleFromBatch = analysisResult.batchResult().getCompatibleCount();
        int actualIncompatibleFromBatch = analysisResult.batchResult().getIncompatibleCount();
        int errorCount = analysisResult.reclassificationResult().correctedErrorCount();
        

        
        // 直接使用批量分析的不兼容数量，而不是通过公式计算
        int finalIncompatibleCount = actualIncompatibleFromBatch;
        
        log.info("最终不兼容数量: {}", finalIncompatibleCount);
        
        double compatibilityPercentage = validSqlCount > 0 ? 
            ((double) actualCompatibleFromBatch / validSqlCount) * PERCENTAGE_MULTIPLIER
            : PERCENTAGE_MULTIPLIER;
        
        double roundedPercentage = Math.round(compatibilityPercentage * PERCENTAGE_PRECISION) / PERCENTAGE_PRECISION;
        
        return new CompatibilityStatisticsResult(finalIncompatibleCount, roundedPercentage);
    }
    
    /**
     * 构建批量分析节点
     */
    public ObjectNode buildBatchAnalysisNode(CompatibilityAnalysisResult analysisResult, 
                                             List<String> validSqls, 
                                             ObjectMapper mapper) {
        BatchAnalysisResponse batchResult = analysisResult.batchResult();
        CompatibilityReclassificationResult reclassificationResult = analysisResult.reclassificationResult();
        FallbackCompatibilityResult fallbackResult = analysisResult.fallbackResult();
        
        // 直接使用批量分析的不兼容数量，避免重复计数
        int finalIncompatibleCount = batchResult.getIncompatibleCount();
        
        ObjectNode batchAnalysisNode = mapper.createObjectNode();
        batchAnalysisNode.put("totalCount", batchResult.getTotalCount());
        batchAnalysisNode.put("compatibleCount", batchResult.getCompatibleCount());
        batchAnalysisNode.put("incompatibleCount", finalIncompatibleCount);
        batchAnalysisNode.put("errorCount", reclassificationResult.correctedErrorCount());
        
        // 构建修正后的错误列表
        ObjectNode correctedErrorsNode = buildCorrectedErrorsNode(batchResult, validSqls, mapper);
        batchAnalysisNode.set("errors", correctedErrorsNode);
        
        // 添加重分类信息
        ObjectNode reclassificationInfo = buildReclassificationInfo(batchResult, reclassificationResult, mapper);
        batchAnalysisNode.set("reclassificationInfo", reclassificationInfo);
        
        // 添加后备检测的不兼容函数信息
        if (fallbackResult != null && !fallbackResult.getIncompatibleSqlIndexes().isEmpty()) {
            ObjectNode incompatibilitiesNode = mapper.createObjectNode();
            fallbackResult.getFunctionDetails().forEach(incompatibilitiesNode::put);
            batchAnalysisNode.set("additionalIncompatibilities", incompatibilitiesNode);
        }
        
        return batchAnalysisNode;
    }
    
    /**
     * 构建修正后的错误节点
     */
    public ObjectNode buildCorrectedErrorsNode(BatchAnalysisResponse batchResult,
                                               List<String> validSqls, 
                                               ObjectMapper mapper) {
        ObjectNode correctedErrorsNode = mapper.createObjectNode();
        if (batchResult.getErrors() != null) {
            for (Map.Entry<Integer, String> errorEntry : batchResult.getErrors().entrySet()) {
                int sqlIndex = errorEntry.getKey();
                String errorMessage = errorEntry.getValue();
                
                // 分析错误时，应该保留所有真正的分析错误
                // 不应该仅仅因为包含某个函数就认为是不兼容，而应该通过规则匹配来判断
                correctedErrorsNode.put(String.valueOf(sqlIndex), errorMessage);
            }
        }
        return correctedErrorsNode;
    }
    
    /**
     * 构建重分类信息节点
     */
    public ObjectNode buildReclassificationInfo(BatchAnalysisResponse batchResult,
                                                 CompatibilityReclassificationResult reclassificationResult,
                                                 ObjectMapper mapper) {
        ObjectNode reclassificationInfo = mapper.createObjectNode();
        reclassificationInfo.put("originalErrorCount", reclassificationResult.originalErrorCount());
        reclassificationInfo.put("reclassifiedAsIncompatible", 
            reclassificationResult.correctedIncompatibleCount() - batchResult.getIncompatibleCount());
        reclassificationInfo.put("finalErrorCount", reclassificationResult.correctedErrorCount());
        return reclassificationInfo;
    }
    
    /**
     * 创建空的批量分析结果
     */
    public BatchAnalysisResponse createEmptyBatchResult() {
        BatchAnalysisResponse batchResult = new BatchAnalysisResponse();
        batchResult.setTotalCount(0);
        return batchResult;
    }
    
    /**
     * 构建摘要信息
     */
    public String buildSummary(String fileName, int totalSqlCount, int validSqlCount, 
                               int compatibleCount, int finalIncompatibleCount, int errorCount) {
        return String.format(
            "ifp框架XML文件 %s 兼容性分析完成： 总SQL语句 %d 个， 有效SQL %d 个， 兼容 %d 个， 不兼容 %d 个，分析错误 %d 个",
            fileName, totalSqlCount, validSqlCount, compatibleCount, finalIncompatibleCount, errorCount
        );
    }
    
    /**
     * 构建JSON处理错误响应
     */
    public String buildJsonErrorResponse(String xmlFilePath, JsonProcessingException e) {
        String details = getExceptionDetails(e);
        return String.format(
            "{\"success\": false, \"error\": \"JSON解析错误\", \"filename\": \"%s\", \"details\": \"%s\", \"timestamp\": \"%s\"}", 
            ifpXMLParser.extractFileNameFromPath(xmlFilePath), details, LocalDateTime.now());
    }
    
    /**
     * 构建IO错误响应
     */
    public String buildIoErrorResponse(String xmlFilePath, IOException e) {
        String details = getExceptionDetails(e);
        return String.format(
            "{\"success\": false, \"error\": \"文件读取错误\", \"filename\": \"%s\", \"details\": \"%s\", \"timestamp\": \"%s\"}", 
            ifpXMLParser.extractFileNameFromPath(xmlFilePath), details, LocalDateTime.now());
    }
    
    /**
     * 构建通用错误响应
     */
    public String buildGenericErrorResponse(String xmlFilePath, Exception e) {
        String details = getExceptionDetails(e);
        return String.format(
            "{\"success\": false, \"error\": \"ifp框架分析过程中发生错误\", \"filename\": \"%s\", \"details\": \"%s\", \"timestamp\": \"%s\"}", 
            ifpXMLParser.extractFileNameFromPath(xmlFilePath), details, LocalDateTime.now());
    }
    
    /**
     * 分析XML文件的兼容性
     */
    public String analyzeXMLCompatibility(String xmlFilePath, boolean isIbatis) {
        try {
            log.info("开始分析XML兼容性: {}, isIbatis: {}", xmlFilePath, isIbatis);

            // 1. 提取SQL语句
            String extractResult = isIbatis ? 
                ibatisXMLParser.extractSQLsFromXML(xmlFilePath) :
                mybatisXMLParser.extractSQLsFromXML(xmlFilePath);

            // 解析提取结果
            ObjectMapper mapper = new ObjectMapper();
            JsonNode extractNode = mapper.readTree(extractResult);

            if (!extractNode.get("success").asBoolean()) {
                String fileName = isIbatis ? 
                    ibatisXMLParser.extractFileNameFromPath(xmlFilePath) :
                    mybatisXMLParser.extractFileNameFromPath(xmlFilePath);
                return String.format("{\"success\": false, \"error\": \"SQL提取失败\", \"filename\": \"%s\", \"details\": \"%s\", \"timestamp\": \"%s\"}",
                        fileName,
                        extractNode.get("errorMessage").asText(),
                        LocalDateTime.now());
            }

            // 2. 过滤出完整的SQL语句（排除片段）
            List<String> validSqls = new ArrayList<>();
            List<JsonNode> sqlDetailsList = new ArrayList<>();
            JsonNode sqlStatements = extractNode.get("sqlStatements");

            // 定义需要跳过的SQL片段标识符
            Set<String> skipPatterns = Set.of(
                    "Base_Column_List", "Example_Where_Clause", "Update_By_Example_Where_Clause"
            );

            for (JsonNode sqlNode : sqlStatements) {
                String sqlId = sqlNode.get("sqlId").asText();
                boolean isComplete = sqlNode.get("isComplete").asBoolean();

                // 跳过SQL片段
                boolean shouldSkip = skipPatterns.stream().anyMatch(pattern -> sqlId.contains(pattern));

                if (shouldSkip) {
                    // 构建跳过的SQL详情
                    ObjectNode detailNode = mapper.createObjectNode();
                    detailNode.put("sqlId", sqlId);
                    detailNode.put("elementType", sqlNode.get("elementType").asText());
                    detailNode.put("isComplete", false);
                    detailNode.put("willAnalyze", false);
                    detailNode.put("skipReason", "SQL片段，不进行兼容性分析");
                    detailNode.put("originalSql", sqlNode.get("originalSql").asText());
                    detailNode.put("fixedSql", "");
                    detailNode.put("startLine", sqlNode.get("startLine").asInt());
                    detailNode.put("endLine", sqlNode.get("endLine").asInt());
                    sqlDetailsList.add(detailNode);
                    continue;
                }

                if (isComplete) {
                    String fixedSql = sqlNode.get("fixedSql").asText();
                    validSqls.add(fixedSql);

                    // 构建将要分析的SQL详情
                    ObjectNode detailNode = mapper.createObjectNode();
                    detailNode.put("sqlId", sqlId);
                    detailNode.put("elementType", sqlNode.get("elementType").asText());
                    detailNode.put("isComplete", true);
                    detailNode.put("willAnalyze", true);
                    detailNode.put("originalSql", sqlNode.get("originalSql").asText());
                    detailNode.put("fixedSql", fixedSql);
                    detailNode.put("startLine", sqlNode.get("startLine").asInt());
                    detailNode.put("endLine", sqlNode.get("endLine").asInt());
                    sqlDetailsList.add(detailNode);
                } else {
                    // 不完整的SQL也记录但不分析
                    ObjectNode detailNode = mapper.createObjectNode();
                    detailNode.put("sqlId", sqlId);
                    detailNode.put("elementType", sqlNode.get("elementType").asText());
                    detailNode.put("isComplete", false);
                    detailNode.put("willAnalyze", false);
                    detailNode.put("skipReason", "SQL语句不完整");
                    detailNode.put("originalSql", sqlNode.get("originalSql").asText());
                    detailNode.put("fixedSql", sqlNode.get("fixedSql").asText());
                    detailNode.put("startLine", sqlNode.get("startLine").asInt());
                    detailNode.put("endLine", sqlNode.get("endLine").asInt());
                    sqlDetailsList.add(detailNode);
                }
            }

            // 3. 批量兼容性分析
            BatchAnalysisResponse batchResult;
            if (!validSqls.isEmpty()) {
                batchResult = sqlAnalysisService.analyzeBatch(validSqls);
            } else {
                // 创建空的批量分析结果
                batchResult = createEmptyBatchResult();
            }

            // 4. 增强兼容性检测
            FallbackCompatibilityResult fallbackResult = isIbatis ? 
                ibatisXMLParser.performFallbackCompatibilityCheck(validSqls, batchResult) :
                mybatisXMLParser.performFallbackCompatibilityCheck(validSqls, batchResult);

            // 5. 重要修正：针对错误SQL进行后备兼容性检测和重新分类
            CompatibilityReclassificationResult reclassificationResult = isIbatis ?
                ibatisXMLParser.performIntelligentReclassification(batchResult, validSqls) :
                mybatisXMLParser.performIntelligentReclassification(batchResult, validSqls);

            // 6. 构建响应
            String fileName = isIbatis ? 
                ibatisXMLParser.extractFileNameFromPath(xmlFilePath) :
                mybatisXMLParser.extractFileNameFromPath(xmlFilePath);
            int totalSqlCount = sqlStatements.size();
            int validSqlCount = validSqls.size();

            // 计算兼容性百分比（直接使用批量分析结果，避免重复计数）
            int finalIncompatibleCount = batchResult.getIncompatibleCount();
            double compatibilityPercentage = validSqlCount > 0 ?
                    ((double) (validSqlCount - finalIncompatibleCount - reclassificationResult.correctedErrorCount()) / validSqlCount) * 100 : 100.0;

            ObjectNode response = mapper.createObjectNode();
            response.put("success", true);
            response.put("fileName", fileName);
            response.put("namespace", extractNode.get("namespace").asText());
            response.put("totalSqlCount", totalSqlCount);
            response.put("validSqlCount", validSqlCount);
            response.put("compatibilityPercentage", Math.round(compatibilityPercentage * 100.0) / 100.0);
            response.put("hasCompatibilityAnalysis", validSqlCount > 0);

            // 批量分析结果（使用修正后的统计）
            CompatibilityAnalysisResult compatibilityResult = new CompatibilityAnalysisResult(
                batchResult,
                fallbackResult,
                reclassificationResult
            );
            ObjectNode batchAnalysisNode = buildBatchAnalysisNode(compatibilityResult, validSqls, mapper);
            
            // 添加重分类信息
            ObjectNode reclassificationInfo = buildReclassificationInfo(batchResult, reclassificationResult, mapper);
            batchAnalysisNode.set("reclassificationInfo", reclassificationInfo);

            // 添加后备检测的不兼容函数信息
            if (fallbackResult.getIncompatibleSqlIndexes() != null && !fallbackResult.getIncompatibleSqlIndexes().isEmpty()) {
                ObjectNode incompatibilitiesNode = mapper.createObjectNode();
                fallbackResult.getFunctionDetails().forEach(incompatibilitiesNode::put);
                batchAnalysisNode.set("additionalIncompatibilities", incompatibilitiesNode);
            }

            response.set("batchAnalysis", batchAnalysisNode);

            // SQL详情
            ArrayNode sqlDetailsArray = mapper.createArrayNode();
            sqlDetailsList.forEach(sqlDetailsArray::add);
            response.set("sqlDetails", sqlDetailsArray);

            // 摘要信息（使用修正后的统计）
            String summary = buildSummary(fileName, totalSqlCount, validSqlCount,
                    batchResult.getCompatibleCount(), finalIncompatibleCount, reclassificationResult.correctedErrorCount());
            response.put("summary", summary);

            response.put("timestamp", LocalDateTime.now().toString());

            String result = mapper.writeValueAsString(response);
            log.info("XML兼容性分析完成: {}, isIbatis: {}", fileName, isIbatis);
            return result;

        } catch (Exception e) {
            log.error("{}框架XML兼容性分析失败: {}", isIbatis ? "iBatis" : "MyBatis", xmlFilePath, e);
            String fileName = isIbatis ? 
                ibatisXMLParser.extractFileNameFromPath(xmlFilePath) :
                mybatisXMLParser.extractFileNameFromPath(xmlFilePath);
            return String.format("{\"success\": false, \"error\": \"%s框架分析过程中发生错误\", \"filename\": \"%s\", \"details\": \"%s\", \"timestamp\": \"%s\"}", 
                isIbatis ? "iBatis" : "MyBatis", fileName, e.getMessage(), LocalDateTime.now());
        }
    }

    /**
     * 获取异常详细信息，确保不返回null
     */
    private String getExceptionDetails(Exception e) {
        if (e == null) {
            return "未知错误";
        }
        
        // 记录完整的异常堆栈信息用于调试
        log.error("异常详细信息:", e);
        
        String message = e.getMessage();
        if (message != null && !message.trim().isEmpty()) {
            return message;
        }
        
        // 如果getMessage()为空，尝试使用异常类名
        String className = e.getClass().getSimpleName();
        
        // 对于 UnsupportedOperationException，尝试获取更多信息，包括调用者
        if (e instanceof UnsupportedOperationException) {
            StackTraceElement[] stackTrace = e.getStackTrace();
            if (stackTrace.length > 1) {
                StackTraceElement caller = stackTrace[1];
                return "UnsupportedOperationException 由 " + caller.getClassName() + "." + caller.getMethodName() + "() 第" + caller.getLineNumber() + "行 调用";
            } else if (stackTrace.length > 0) {
                return "UnsupportedOperationException 在 " + stackTrace[0].getClassName() + "." + stackTrace[0].getMethodName() + "() 第" + stackTrace[0].getLineNumber() + "行";
            }
        }
        
        if (e.getCause() != null && e.getCause().getMessage() != null) {
            return className + ": " + e.getCause().getMessage();
        }
        
        return className + "异常";
    }
}